package cn.com.dhc.danlu.widget.banner;

import android.content.Context;
import android.content.res.TypedArray;
import android.net.Uri;
import android.os.Looper;
import android.support.v4.view.PagerAdapter;
import android.support.v4.view.ViewPager;
import android.util.AttributeSet;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.RelativeLayout;

import com.facebook.drawee.drawable.ScalingUtils.ScaleType;
import com.facebook.drawee.generic.GenericDraweeHierarchy;
import com.facebook.drawee.generic.GenericDraweeHierarchyBuilder;
import com.facebook.drawee.view.SimpleDraweeView;

import java.lang.ref.WeakReference;
import java.util.ArrayList;
import java.util.List;
import java.util.Stack;

import cn.com.dhc.danlu.R;
import cn.com.dhc.danlu.util.CommonUtils;
import cn.com.dhc.danlu.util.WeakHandler;
import cn.com.dhc.danlu.widget.SlowViewPager;

import static cn.com.dhc.danlu.dlware.global.DanluApplication.agent;

/**
 * User: Geek_Soledad(wuhaiyang@danlu.com)
 * Date: 2016-08-09
 * Time: 09:37
 * Description: 公共库 自动轮播条
 */
public class AutoBannerPager extends RelativeLayout {
    private final List<String> mPicDatas = new ArrayList ();
    private WeakHandler mWeakHandler;
    private SlowViewPager mSlowViewPager;
    private AutoRunableTask mAutoRunableTask;
    private ScaleType scaleType = null;

    /**
     * 指示器
     */
    private LinearLayout mLlIndicatorContainer;
    /**
     * 当前所在页面
     */
    private int mCurrentPageIndex = 0;
    /**
     * 是否开启自动轮播
     */
    private boolean isAutoRunable = true;
    /**
     * 是否开启无限循环滑动
     */
    private boolean isOpenInfinite = true;
    /**
     * 延迟时间
     */
    private int mDelayTime;
    private int mSelectorIndicatorId;
    private OnPageClickListener mPageClickListener;
    /**
     * 当前轮播任务是否正在执行
     */
    private boolean isRunable = false;

    public AutoBannerPager (Context context) {
        this (context, null);
    }

    public AutoBannerPager (Context context, AttributeSet attrs) {
        this (context, attrs, 0);
    }

    public AutoBannerPager (Context context, AttributeSet attrs, int defStyleAttr) {
        super (context, attrs, defStyleAttr);

        TypedArray array = context.obtainStyledAttributes (attrs, R.styleable.dl_auto_banner_pager);
        isAutoRunable = array.getBoolean (R.styleable.dl_auto_banner_pager_is_auto_runable, true);
        isOpenInfinite = array.getBoolean (R.styleable.dl_auto_banner_pager_is_infinite, true);
        mDelayTime = array.getInteger (R.styleable.dl_auto_banner_pager_delay_time, 3000);
        mSelectorIndicatorId = array.getResourceId (R.styleable.dl_auto_banner_pager_indicator_seletor, R.drawable.selector_banner_indicator);
        array.recycle ();
        init ();
    }

    public void refreshBanner (List<String> imgs) {
        if (null != imgs && !imgs.isEmpty ()) {
            mPicDatas.clear ();
            mPicDatas.addAll (imgs);
            mSlowViewPager.getAdapter ().notifyDataSetChanged ();
            if (null == mAutoRunableTask) {
                mAutoRunableTask = new AutoRunableTask ();
            }
            if (imgs.size () == 1) {
                mLlIndicatorContainer.removeAllViews ();
                mAutoRunableTask.stopTask ();
            } else {
                refreshIndicatorView (imgs.size ());
                if (isOpenInfinite) {
                    mSlowViewPager.setCurrentItem (1000 * imgs.size ());
                } else {
                    mSlowViewPager.setCurrentItem (0);
                }
                if (isAutoRunable) {
                    mAutoRunableTask.startTask ();
                } else {
                    mAutoRunableTask.stopTask ();
                }
            }
        }
    }

    /**
     * 刷新指示器
     */
    private void refreshIndicatorView (int size) {
        mLlIndicatorContainer.removeAllViews ();
        LinearLayout.LayoutParams indicatorIvLp = new LinearLayout.LayoutParams (CommonUtils.dipToPx (getContext (), 5), CommonUtils.dipToPx (getContext (), 5));
        for (int i = 0; i < size; i++) {
            ImageView indicator = new ImageView (getContext ());
            if (i != 0) {
                indicatorIvLp.setMargins (CommonUtils.dipToPx (getContext (), 5), 0, 0, 0);
            }
            indicator.setLayoutParams (indicatorIvLp);
            indicator.setImageResource (mSelectorIndicatorId);
            indicator.setEnabled (false);
            mLlIndicatorContainer.addView (indicator);
        }
        mLlIndicatorContainer.getChildAt (0).setEnabled (true);
    }

    @Override
    public boolean dispatchTouchEvent (MotionEvent ev) {
        if (!isAutoRunable || mSlowViewPager.getAdapter ().getCount () <= 1) {
            return super.dispatchTouchEvent (ev);
        }
        switch (ev.getAction ()) {
            case MotionEvent.ACTION_DOWN:
                mAutoRunableTask.stopTask ();
                break;
            case MotionEvent.ACTION_CANCEL:
                mAutoRunableTask.startTask ();
                break;
            case MotionEvent.ACTION_UP:
                mAutoRunableTask.startTask ();
                break;
            default:
                break;
        }
        return super.dispatchTouchEvent (ev);
    }

    private void attachIndicatorContainer () {
        mLlIndicatorContainer = new LinearLayout (getContext ());
        mLlIndicatorContainer.setOrientation (LinearLayout.HORIZONTAL);
        RelativeLayout.LayoutParams lp1 = new RelativeLayout.LayoutParams (LayoutParams.WRAP_CONTENT, LayoutParams.WRAP_CONTENT);
        lp1.addRule (ALIGN_PARENT_BOTTOM);
        lp1.addRule (CENTER_HORIZONTAL);
        lp1.setMargins (0, 0, 0, CommonUtils.dipToPx (getContext (), 10));
        addView (mLlIndicatorContainer, lp1);
    }

    private void init () {
        mWeakHandler = new WeakHandler (Looper.getMainLooper ());
        mSlowViewPager = new SlowViewPager (getContext ());
        RelativeLayout.LayoutParams lp = new RelativeLayout.LayoutParams (RelativeLayout.LayoutParams.MATCH_PARENT, RelativeLayout.LayoutParams.MATCH_PARENT);
        addView (mSlowViewPager, lp);

        attachIndicatorContainer ();

        mSlowViewPager.addOnPageChangeListener (new ViewPager.OnPageChangeListener () {
            @Override
            public void onPageScrolled (int position, float positionOffset, int positionOffsetPixels) {
            }

            @Override
            public void onPageSelected (int position) {
                if (mPicDatas.size () <= 1) {
                    return;
                }
                mCurrentPageIndex = position % mPicDatas.size ();
                for (int i = 0; i < mLlIndicatorContainer.getChildCount (); i++) {
                    View view = mLlIndicatorContainer.getChildAt (i);
                    if (null != view) {
                        view.setEnabled (false);
                    }
                }
                View enableView = mLlIndicatorContainer.getChildAt (mCurrentPageIndex);
                if (null != enableView) {
                    enableView.setEnabled (true);
                }
            }

            @Override
            public void onPageScrollStateChanged (int state) {
            }
        });
        mSlowViewPager.setAdapter (new InnerPagerAdapter ());
    }

    public void setIsAutoRunable (boolean isAutoRunable) {
        this.isAutoRunable = isAutoRunable;
    }

    public void setIsOpenInfinite (boolean isOpenInfinite) {
        this.isOpenInfinite = isOpenInfinite;
    }

    public void setScaleType (ScaleType scaleType) {
        this.scaleType = scaleType;
    }

    public void setPageClickListener (OnPageClickListener pageClickListener) {
        mPageClickListener = pageClickListener;
    }

    public interface OnPageClickListener {
        void onPageClicked (int pos);
    }

    private class AutoRunableTask implements Runnable {
        @Override
        public void run () {
            int nextItem = mSlowViewPager.getCurrentItem () + 1;
            mSlowViewPager.setCurrentItem (nextItem % mSlowViewPager.getAdapter ().getCount ());
            mWeakHandler.postDelayed (this, mDelayTime);
        }

        void startTask () {
            if (isRunable) {
                return;
            }
            isRunable = true;
            mWeakHandler.removeCallbacks (this);
            mWeakHandler.postDelayed (this, mDelayTime);
        }

        void stopTask () {
            if (!isRunable) {
                return;
            }
            isRunable = false;
            mWeakHandler.removeCallbacks (this);
        }
    }

    private class InnerPagerAdapter extends PagerAdapter {
        private Stack<WeakReference<SimpleDraweeView>> mCacheViews = new Stack<> ();

        @Override
        public int getCount () {
            return isOpenInfinite && mPicDatas.size () > 1 ? Integer.MAX_VALUE : mPicDatas.size ();
        }

        @Override
        public Object instantiateItem (ViewGroup container, int position) {
            SimpleDraweeView imageView = null;
            WeakReference<SimpleDraweeView> refView = null;
            while (mCacheViews.size () > 0) {
                refView = mCacheViews.pop ();
                imageView = refView.get ();
            }
            if (null != imageView) {
                refView.clear ();
            } else {
                imageView = new SimpleDraweeView (getContext ());
                GenericDraweeHierarchyBuilder builder = new GenericDraweeHierarchyBuilder (getResources ());
                GenericDraweeHierarchy hierarchy = builder.setFadeDuration (300)
                        .setPlaceholderImage (getResources ().getDrawable (R.drawable.icon_home_banner1_loadding), ScaleType.FIT_XY)
                        .setActualImageScaleType ((null == scaleType) ? ScaleType.FIT_XY : scaleType)
                        .build ();
                // 对于同一个View，请不要多次调用setHierarchy
                imageView.setHierarchy (hierarchy);
                imageView.setTag (position);
                imageView.setOnClickListener (new OnClickListener () {
                    @Override
                    public void onClick (View v) {
                        if (null != mPageClickListener) {
                            mPageClickListener.onPageClicked (mCurrentPageIndex);
                        }
                    }
                });
            }
            position = position % mPicDatas.size ();
            String url = mPicDatas.get (position);
            if (url.contains ("@") && agent.isWifi ()) {
                url = url.substring (0, url.indexOf ("@"));
            }
            imageView.setImageURI (Uri.parse (url));
            container.addView (imageView);
            return imageView;
        }

        @Override
        public void destroyItem (ViewGroup container, int position, Object object) {
            container.removeView ((View) object);
            mCacheViews.push (new WeakReference<> ((SimpleDraweeView) object));
        }

        @Override
        public boolean isViewFromObject (View view, Object object) {
            return view == object;
        }
    }
}
